

#ifndef _SDK_LLIST_H
#  define _SDK_LLIST_H

#  include <config.h>
#  include <sdk_mem.h>

/* Data structures. */

unsigned short sdk_nums[16];

/* This isn't *actually* a linked list; but it will act like one.
   It is heavily optimzed for speed as this is where the solver spends most of
   its time. */
struct _sdk_llist {

  unsigned short list;
  unsigned char len;

}__attribute__((aligned (4)));
typedef struct _sdk_llist sdk_llist_t;

/* Defines to make things easier. */

#  define SDK_ALLOC_LLIST() (sdk_llist_t *)sdk_malloc(sizeof(sdk_llist_t))
#  define SDK_DEALLOC_LLIST(LLIST) sdk_free(LLIST, sizeof(sdk_llist_t))
#  define SDK_LLIST_LEN(LLIST) ((LLIST)->len)
#  define SDK_LLIST_ITERATE(LLIST, ELEM_NUM, ELEM)	\
  ELEM = sdk_nums[0] & LLIST->list;\
  for ( ELEM_NUM = 1; ELEM_NUM <= SDK_WIDTH; \
	ELEM = sdk_nums[ELEM_NUM++] & LLIST->list)

#  define SDK_0  (0)
#  define SDK_1  (1<<0)
#  define SDK_2  (1<<1)
#  define SDK_3  (1<<2)
#  define SDK_4  (1<<3)
#  define SDK_5  (1<<4)
#  define SDK_6  (1<<5)
#  define SDK_7  (1<<6)
#  define SDK_8  (1<<7)
#  define SDK_9  (1<<8)
#  define SDK_10 (1<<9)
#  define SDK_11 (1<<10)
#  define SDK_12 (1<<11)
#  define SDK_13 (1<<12)
#  define SDK_14 (1<<13)
#  define SDK_15 (1<<14)
#  define SDK_16 (1<<15)


/* Functions for manipulating the list. */
/* These all should be implemented in assembler at some point. */
int          sdk_llist_contains(sdk_llist_t *, unsigned int);
int          sdk_llist_add(sdk_llist_t *, unsigned int);
int          sdk_llist_remove(sdk_llist_t *, unsigned int);
int          sdk_llist_size(sdk_llist_t *);
int          sdk_llist_lowest_num(sdk_llist_t *);
void         sdk_llist_print(sdk_llist_t *);
void         sdk_llist_print_lite(sdk_llist_t *);
sdk_llist_t *sdk_llist_full_list();

#endif
